﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Wlh.TextBoxLabel
{
    public partial class FormTbAndLbl : Form
    {
        /// <summary>
        /// Tab 跳转表
        /// </summary>
        private readonly Dictionary<string, string> _TabMap = new Dictionary<string, string>();

        public FormTbAndLbl()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            tbInput.LostFocus += tbInput_LostFocus;

            InitTabMap();
        }

        /// <summary>
        /// 初始化 Tab 跳转表
        /// </summary>
        private void InitTabMap()
        {
            // 加入From，To的控件名称，表示按下Tab键从From跳掉To位置
            _TabMap.Add(nameof(tbInput), nameof(lblInfo));
        }
        
        /// <summary>
        /// 检查输入内容能否被3整除
        /// </summary>
        /// <returns></returns>
        private bool Check()
        {
            try
            {
                if (double.Parse(tbInput.Text) % 3 == 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 失去焦点时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbInput_LostFocus(object sender, EventArgs e)
        {
            lblInfo.Text = Check().ToString();
        }

        /// <summary>
        /// 这个重载函数里可以预先捕捉到一些按键，比如被系统默认捕获了的Tab键
        /// 如果要改写Tab键的默认动作，要返回true，表示你已经处理过这个按键了
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            Control ctl = this.ActiveControl;
            if (keyData == Keys.Tab)
            {
                if (ctl != null && _TabMap.Keys.Contains(ctl.Name))
                {
                    var toCtrls = this.Controls.Find(_TabMap[ctl.Name], true);
                    if (toCtrls.Length > 0)
                    {
                        //检查父容器是否是隐藏的
                        ActivieParentContainerIfNeeded(toCtrls[0]);
                        toCtrls[0].Focus();
                        //确实获得了焦点，再吞噬这个按键动作
                        if (toCtrls[0].Focused)
                        {
                            return true;
                        }
                    }
                }
            }

            bool ret = base.ProcessCmdKey(ref msg, keyData);
            return ret;
        }

        /// <summary>
        /// 有一些控件隐藏在了TabControl的后面，造成Focus不成功。
        /// 因为这些控件的Visible为False，必须先使他们的父控件TabPage先选中
        /// </summary>
        /// <param name="child"></param>
        private void ActivieParentContainerIfNeeded(Control child)
        {
            if (child.Visible)
            {
                return;
            }

            Control parent = child.Parent;
            while (parent != null)
            {
                if (parent is TabPage)
                {
                    break;
                }

                parent = parent.Parent;
            }

            if (parent is TabPage)
            {
                TabControl tabCtrl = (TabControl)parent.Parent;
                tabCtrl.SelectedTab = (parent as TabPage);
            }
        }

        /// <summary>
        /// 按键（Enter）时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbInput_KeyDown(object sender, KeyEventArgs e)
        {
            //if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab) //Tab键无效;
            if (e.KeyCode == Keys.Enter)
            {
                lblInfo.Text = Check().ToString();
            }  
        }

        /// <summary>
        /// 点击窗体时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Click(object sender, EventArgs e)
        {
            lblInfo.Focus();
        }
    }
}
